﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using SmoLiteApi.Sql;
using SmoLiteApi.Helper;

namespace SmoLiteApi
{
    /// <summary/>
    public class Server
    {
        private SqlConnection _sqlConnection;
        private ServerConnection _serverConnection;
        private LoginCollection _loginCollection;
        private DatabaseCollection _databaseCollection;

        /// <summary/>
        public Server(SqlConnection sqlConnection)
        {
            this._sqlConnection = sqlConnection;
            this._serverConnection = new ServerConnection(sqlConnection);
            this._loginCollection = new LoginCollection(this);
            this._databaseCollection = new DatabaseCollection(this);
        }

        /// <summary/>
        public Server()
        {
            this._sqlConnection = new SqlConnection();
            this._serverConnection = new ServerConnection(this._sqlConnection);
            this._loginCollection = new LoginCollection(this);
            this._databaseCollection = new DatabaseCollection(this);
        }

        /// <summary/>
        public LoginCollection Logins
        {
            get { return this._loginCollection; }
        }

        /// <summary/>
        public DatabaseCollection Databases
        {
            get { return this._databaseCollection; }
        }

        /// <summary/>
        public ServerConnection ConnectionContext
        {
            get { return this._serverConnection; }
        }

        /// <summary/>
        public void KillDatabase(string name)
        {
            DatabaseDropSql userCreateSql = new DatabaseDropSql();

            // set attributes
            userCreateSql.AddObject(new { Name = name });

            using (SqlCommandHelper sqlCommandHelper = SqlCommandHelper.FetchSqlCommand(this.FetchSqlConnection(), userCreateSql.Render()))
            {
                // run the command
                sqlCommandHelper.ExecuteNonQuery();
            }
        }

        /// <summary/>
        public void KillAllProcesses(string name)
        {
            List<int> processes = new List<int>();

            ProcessSelectSql processSelectSql = new ProcessSelectSql();

            // set attributes
            processSelectSql.AddObject(new { Name = name });

            using (SqlCommandHelper sqlCommandHelper = SqlCommandHelper.FetchSqlCommand(this.FetchSqlConnection(), processSelectSql.Render()))
            {
                using (SqlDataReader sqlDataReader = sqlCommandHelper.ExecuteReader())
                {
                    while (sqlDataReader.Read())
                    {
                        // record the id
                        processes.Add(sqlDataReader.GetInt32(sqlDataReader.GetOrdinal(Constant.PARAMETER_REQUEST_SESSION_ID)));
                    }
                }
            }

            foreach (int process in processes)
            {
                ProcessKillSql processKillSql = new ProcessKillSql();

                // set attributes
                processKillSql.AddObject(new { Name = process });

                using (SqlCommandHelper sqlCommandHelper = SqlCommandHelper.FetchSqlCommand(this.FetchSqlConnection(), processKillSql.Render()))
                {
                    // run the command
                    sqlCommandHelper.ExecuteNonQuery();
                }
            }
        }

        /// <summary/>
        internal SqlConnection FetchSqlConnection()
        {
            // is the database name correct
            if (!string.Equals(this._sqlConnection.Database, Constant.DATABASE_MASTER))
            {
                this._sqlConnection.ChangeDatabase(Constant.DATABASE_MASTER);
            }
            
            // return the connection
            return this._sqlConnection;
        }

        /// <summary/>
        internal SqlConnection FetchSqlConnection(string database)
        {
            // is the database name correct
            if (!string.Equals(this._sqlConnection.Database, database))
            {
                this._sqlConnection.ChangeDatabase(database);
            }

            // return the connection
            return this._sqlConnection;
        }
    }
}
